import Dexie from "dexie";


// var db = new Dexie('mydatabase');

export interface Data {
    id?: number, // 主键
    typeId?: number, // 类型Id
    typeName?: string, // 类型名称
    value?: number, // 值
    typeUnit?: string, // 类型单位
    timestamp: number, // 时间戳
    date?: string, //日期字符串
}

export interface Type {
    id?: number, // 主键
    name?: string, // 类型名
    unit?: string, // 类型的单位
}

// datas: 每日的数据
// types: 想要记录的数据
// db.version(1).stores({
//     //id<Int>: 主键, typeId<Int>: 类型Id, typeName<Str>: 类型名称, value<Number>: 值, typeUnit<Str>: 类型单位, timestamp<Number>: 时间戳, date<Str>: 日期字符串
//     dataTable: "++id, typeId, typeName, value, typeUnit, timestamp, date",
//     //id<int>: 主键, name<Str>: 类型名, unit: 类型的单位
//     typesTable: "++id, name, unit"
// });

class MyDataDB extends Dexie {
    public dataTable: Dexie.Table<Data, number>;
    public typesTable: Dexie.Table<Type, number>;

    public constructor() {
        super("mydatabase");
        this.version(1).stores({
            //id<Int>: 主键, typeId<Int>: 类型Id, typeName<Str>: 类型名称, value<Number>: 值, typeUnit<Str>: 类型单位, timestamp<Number>: 时间戳, date<Str>: 日期字符串
            dataTable: "++id, typeId, typeName, value, typeUnit, timestamp, date",
            //id<int>: 主键, name<Str>: 类型名, unit: 类型的单位
            typesTable: "++id, name, unit"
        })
        this.dataTable = this.table("dataTable")
        this.typesTable = this.table("typesTable")
    }
}
var db = new MyDataDB()
/**
 * 查看全部类型列表
 */
export function listTypes() {
    return db.transaction('r', db.typesTable, async () => {
        var result = await db.typesTable.toCollection().toArray()
        return { code: 0, data: result }
    })
}
/**
 * 根据类型ID获取数据
 * @param id 类型ID
 * @returns 
 */
export function getTypeByID(id: number) {
    return db.transaction('r', db.typesTable, async () => {
        var result = await db.typesTable.get(id)
        return { code: 0, data: result }
    })
}

/**
 * 新增类型
 * @param {Type} params {id,name,unit} 查询条件 
 */
export function addType(params: Type) {
    return db.transaction('rw', db.typesTable, async () => {
        if (!params || !params.name || !params.unit) {
            throw new Error('新增类型字段不全')
        }
        return db.typesTable.add({ name: params.name, unit: params.unit }).then(() => {
            return { code: 0, msg: "新增成功" }
        }).catch((e) => { throw e });
    })
}

/**
 * 删除类型
 */
export function delType(id: number) {
    return db.transaction('rw', db.typesTable, async () => {
        if (!id) {
            throw new Error('ID未知')
        }
        return db.typesTable.delete(id).then(() => {
            return { code: 0, msg: "删除成功" }
        }).catch((e) => { throw e });
    })
}

/**
 * 查询某天的数据
 * @param {Object} params 
 */
export function listDataOneDay(params: { [key: string]: any } = { id: undefined, date: '' }) {
    return db.transaction('r', db.dataTable, async () => {
        let result, date: Date;
        if (params.date && new Date(params.date).toString() !== 'Invalid Date') {
            date = new Date(params.date.toLocaleDateString());
        } else {
            date = new Date(new Date().toLocaleDateString());
        }
        let nextDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
        let myparams = Object.assign({}, params);
        delete myparams.date
        if (Object.keys(myparams).length === 0) {
            result = await db.dataTable.filter((data) => {
                return data.timestamp > date.getTime() && data.timestamp < nextDate.getTime();
            }).toArray();
        } else {
            result = await db.dataTable.where(myparams).filter((data) => {
                return data.timestamp > date.getTime() && data.timestamp < nextDate.getTime();
            }).toArray();
        }
        return ({ 'code': 0, 'data': result })
    })
}

/**
 * 获取一个返回的数据
 * @param {*} params 
 * {beginDate:开始的日期 y/m/d,endDate: 结束的日期 y/m/d}
 */
export function listDataRange(params: { [key: string]: any } = { id: undefined }) {
    return db.transaction('r', db.dataTable, async () => {
        let result, beginDate: Date, endDate: Date;
        let myparams = Object.assign({}, params)
        if (myparams.beginDate && new Date(myparams.beginDate).toString() !== 'Invalid Date'
            && myparams.endDate && new Date(myparams.endDate).toString() !== 'Invalid Date') {
            beginDate = new Date(myparams.beginDate);
            endDate = new Date(myparams.endDate);
            endDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate() + 1);
        } else {
            beginDate = new Date(new Date().toLocaleDateString());
            endDate = new Date(beginDate.getFullYear(), beginDate.getMonth(), beginDate.getDate() + 1);
        }
        delete myparams.beginDate;
        delete myparams.endDate;
        if (Object.keys(myparams).length === 0) {
            result = await db.dataTable.filter((data) => {
                return data.timestamp > beginDate.getTime() && data.timestamp < endDate.getTime();
            }).toArray();
        } else {
            result = await db.dataTable.where(myparams).filter((data) => {
                return data.timestamp > beginDate.getTime() && data.timestamp < endDate.getTime();
            }).toArray();
        }
        return ({ 'code': 0, 'data': result })
    })
}

/**
 * 新增数据
 * @param {Object} params 
 */
export function addData(params: Data) {
    return db.transaction('rw', db.dataTable, async () => {
        if (!params || !params.value || !params.typeId) {
            throw new Error('新增类型字段不全')
        }
        if (params.date) {
            params.timestamp = new Date(params.date).getTime() + 12 * 60 * 60 * 1000
        } else {
            params.timestamp = Date.now()
        }
        return db.dataTable.add({...params}).then(() => {
            return { code: 0, msg: "新增成功" }
        }).catch((e) => { throw e });
    })
}

/**
 * 删除数据
 */
export function deleteData(id: number) {
    return db.transaction('rw', db.dataTable, async () => {
        if (!id) {
            throw new Error('ID未知')
        }
        return db.dataTable.delete(id).then(() => {
            return { code: 0, msg: "删除成功" }
        }).catch((e) => { throw e });
    })
}

/**
 * 修改数据
 */
export function updateData(id: number, data: Data) {
    return db.transaction('rw', db.dataTable, async () => {
        if (!id) {
            throw new Error('ID未知')
        }
        return db.dataTable.update(id, data).then(() => {
            return { code: 0, msg: "修改成功" }
        }).catch((e) => { throw e });
    })
}

/**
 * 导入数据
 * @param {*} json 
 */
export function importData(json: { [key: string]: any }) {
    if (!json.dataTable || !json.typesTable) {
        throw new Error('数据错误')
    }
    return db.transaction('rw', db.dataTable, db.typesTable, async () => {
        await db.dataTable.bulkPut(json.dataTable)
        await db.typesTable.bulkPut(json.typesTable)
        return { code: 0, msg: "导入成功" }
    })
}

interface AllData {
    dataTable: Array<Data>,
    typesTable: Array<Type>
}
/**
 * @returns {Object} 返回所有数据
 */
export function outputData() {
    let allData: AllData = {
        dataTable: [],
        typesTable: []
    }
    return db.transaction('r', db.dataTable, db.typesTable, async () => {
        try {
            allData.dataTable = await db.dataTable.toCollection().toArray()
            allData.typesTable = await db.typesTable.toCollection().toArray()
            const a = document.createElement('a')
            // 创建一个blob对象
            const blob = new Blob([JSON.stringify(allData)], { type: 'application/json' })
            // 创建URL
            a.href = URL.createObjectURL(blob)
            a.download = '导出数据.json'
            a.click()
            URL.revokeObjectURL(a.href)
        } catch (error) {
            throw new Error
        }
    })
}